home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / gold / indivMethods.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  20.4 KB  |  840 lines

  1. /*
  2.  * The original copyright owners of the accompanying source code files have
  3.  * agreed to place such code into the public domain.  Accordingly, anyone
  4.  * who receives or obtains a copy of such source code is freely entitled to
  5.  * reproduce, use and otherwise exploit such code (including the right to
  6.  * make derivative works), at his/her own risk and expense, without any
  7.  * obligation or liability to the original copyright owners.
  8.  *
  9.  * We would appreciate (but do not require) that the following message be
  10.  * included in any derivative works:
  11.  *
  12.  * "Portions of this program were developed by Peter Broadwell, Rob Myers
  13.  * and Robin Schaufler while working in Silicon Valley."
  14.  *
  15.  * The accompanying source code files and related documentation materials
  16.  * are distributed on an "AS IS" basis, without any warranties or
  17.  * guarantees of any kind.  All implied warranties, including the implied
  18.  * warranties of merchantability and of fitness for any particular purpose,
  19.  * are expressly disclaimed.
  20.  */
  21. #include "gl.h"
  22. #include "geom.h"
  23. #include "class.h"
  24. #include "selectors.h"
  25. #include "classIds.h"
  26. #include "mbox.h"
  27. #include "individual.h"
  28. #include "behavior.h"
  29. #include "colors.h"
  30. #include "pick.h"
  31. #include "doers.h"
  32. #include "panel.h"
  33. #include "valuator.h"
  34. #include "objIds.h"
  35.  
  36. #define PI 3.14159265358979323844
  37. #define DEG(x) ((float)x*(float)180/PI)
  38. #define RAD(x) ((float)x*PI/(float)180)
  39.  
  40. extern behavior advancerTemplate;
  41. extern behavior expanderTemplate;
  42. extern behavior surfDieTemplate;
  43. extern char frozen;
  44. extern char dobackground;
  45. extern subscr *findvars();
  46. model *replicateMsegs();
  47. extern model selectModel;
  48. extern masterPanel *thePanel;
  49. extern int unsophistication;
  50. extern int controls;
  51. extern individual *us;
  52. extern long fishPop;
  53. extern int dumper;
  54.  
  55.     /*
  56.      *  current selection
  57.      */
  58. individual *curIndiv = NULL;
  59. int inNothing = TRUE;
  60.  
  61.  
  62.     /*
  63.      *  instantiate and initialize an individual's model list
  64.      */
  65.     individual *
  66. replicateModel(self)
  67.     register individual *self;
  68. {
  69.     /* reproduce list of model segments */
  70.     self->descr = replicateMsegs(self->descr);
  71. }
  72.  
  73.     /*
  74.      * instantiate and initialize a model tree, beginning with firstModel
  75.      */
  76.     model *
  77. replicateMsegs(firstModel)
  78.     register model *firstModel;
  79. {
  80.     register model *m, *newm, *lastm;
  81.  
  82.     for (m = firstModel, lastm = NULL; m; m = m->next, lastm = newm) {
  83.     newm = (model *)gfmalloc(sizeof(model));
  84. #ifdef MALDEBUG
  85.     if(*(char *)newm) {
  86.         printf("replicatingMsegs: onto non empty gfmalloc 0x%x\n",newm);
  87.     }
  88. #endif /* MALDEBUG */
  89.     bcopy(m, newm, sizeof(model));
  90.     newm->compiled = FALSE;
  91.     initcolor(newm);
  92.     newm->kids = replicateMsegs(newm->kids);
  93.     if (lastm)
  94.          lastm->next = newm;
  95.     else firstModel  = newm;
  96.     }
  97.     return firstModel;
  98. }
  99.  
  100.     /*
  101.      *  initialize the color slot choice for a model segment
  102.      */
  103. initcolor(m)
  104.     register model *m;
  105. {
  106.     rgbcolor hue;
  107.  
  108.     if(m->color >= BACK_GROUND_BASE) return;
  109.     gmcolor(m->color, &hue.r, &hue.g, &hue.b);
  110.     m->color = getMapIndex();
  111.     mapcaller(m->color, hue.r, hue.g, hue.b);
  112. }
  113.  
  114.     /*
  115.      *  service each individual's tic, by servicing each of its subscribedTos
  116.      */
  117. /* ARGSUSED */
  118.     individual *
  119. serviceTic(self, argtype, rootObject)
  120.     register individual *self;
  121.     long argtype;
  122.     mailbox *rootObject;
  123. {
  124.     register subscr *sentry;
  125.     register subscr *tmp_next;
  126.  
  127.     pushmatrix();
  128.     if (!frozen) {
  129.     for (sentry=self->them.subscribedTo; sentry; sentry = tmp_next) {
  130.         self->curVars = sentry;
  131.         tmp_next = sentry->next;
  132.         if(Msg(sentry->member, DOIT, INSTARG, self) == 0) {
  133.         popmatrix();
  134.         return NULL;
  135.         }
  136.     }
  137.     }
  138.     Msg(self, DRAW, NOARG, NULL);
  139.     popmatrix();
  140.     return self;
  141. }
  142.  
  143.  
  144. moveUp(self)
  145.     register individual *self;
  146. {
  147.     double hyp, atan2(), sqrt();
  148.  
  149.     if (!frozen) {
  150.         /* rotate individual to (position-lastPosition) */
  151.     self->delta.x = self->position.x - self->lastPosition.x;
  152.     self->delta.y = self->position.y - self->lastPosition.y;
  153.     self->delta.z = self->position.z - self->lastPosition.z;
  154.  
  155.         /* the following makes the fish follow her nose */
  156.     hyp = sqrt(fabs((float)(self->delta.x * self->delta.x +
  157.                self->delta.y * self->delta.y)));
  158.  
  159.     if (hyp == 0.0) {
  160.         self->rotation.y =
  161.         ((self->delta.z > 0) ? self->delta.z : -self->delta.z) * 90 * 10;
  162.         self->rotation.z = 0;
  163.     }
  164.     else {
  165.         self->rotation.y = 10 * DEG(atan2(hyp, (float)self->delta.z));
  166.         self->rotation.z = 10 * DEG(atan2((float)self->delta.y,
  167.                           (float)self->delta.x));
  168.     }
  169.     self->rotation.x = 0;
  170.  
  171.     /*
  172.     printf("self->delta is %d %d %d \t", self->delta.x,
  173.                          self->delta.y,
  174.                          self->delta.z);
  175.     printf("rot is %d %d %d \n",self->rotation.x,
  176.                     self->rotation.y,
  177.                     self->rotation.z); /* */
  178.  
  179.     self->lastPosition = self->position;
  180.     }
  181. }
  182.  
  183.  
  184.     /* 
  185.      * draw an individual with each model segment
  186.      */
  187. drawIndividual(self)
  188.     register individual *self;
  189. {
  190.     register model *aModel;
  191.     register subscr *entry; /* only looked at when debugging */
  192.  
  193.     Msg(self, MOVE, 0, NULL);
  194.     aModel = self->descr;
  195.     if((aModel && aModel->color < BACK_GROUND_BASE) || dobackground) {
  196.     if (entry = findvars(self, VOXEL))
  197.         newVoxPosition(entry->member, &self->position, self);
  198.  
  199.         /*
  200.          *  transform entire individual to its new orientation
  201.          */
  202.     translate((float)self->position.x,
  203.           (float)self->position.y,
  204.           (float)self->position.z);
  205.  
  206.     scale(self->scale, self->scale, self->scale);
  207.  
  208.     rotate(self->rotation.z , 'z');
  209.     rotate(self->rotation.y , 'y');
  210.     /* rotate(self->rotation.x , 'x'); /* not needed yet */
  211.  
  212.         /*
  213.          *  counteract effect of rotating the fishbowl
  214.          */
  215.     rotate(-900, 'y');
  216.  
  217.     dolater(self);
  218.     }
  219. }
  220.  
  221.     /*
  222.      * draw each model segment
  223.      */
  224. drawModels(self,unit)
  225.     individual *self;
  226.     float unit[8];
  227. {
  228.     long oct;
  229.     float z,w;
  230.  
  231.     w = unit[7];
  232.     if(w != 0.0) {
  233.     z = unit[6]/w;
  234.     }
  235.     else {
  236.     z = unit[6];
  237.     }
  238.  
  239.     if(unit[2]<z)
  240.     oct = 4;
  241.     else
  242.     oct = 0;
  243.  
  244. if(self->them.me.myClass->classId == 0) burp("drawModels",self);
  245.     if(self->flags & ORDER) {
  246.     if(oct>=4) {    /* fish going away from us, so draw body then tail */
  247.         drawModel(self->descr,self,0);
  248.         drawModel(self->descr->next,self,0);
  249.     }
  250.     else {
  251.         drawModel(self->descr->next,self,0);
  252.         drawModel(self->descr,self,0);
  253.     }
  254.     }
  255.     else {
  256.     drawModel(self->descr,self,1);
  257.     }
  258.     if(self->flags & PICKED) {
  259.     drawModel(&selectModel, self,0);
  260.     }
  261. }
  262.  
  263.     /*
  264.      * transform each model segment, to set up its actual drawing
  265.      */
  266. drawModel(firstModel, indiv, chain)
  267.     register model *firstModel;
  268.     register individual *indiv;
  269.     register int chain;
  270. {
  271.     register model *aModel;
  272.     
  273.     for (aModel = firstModel; aModel ; aModel = chain ? aModel->next : NULL) {
  274. if(aModel->kids == aModel->next && aModel->kids != NULL) burp("drawModel",indiv);
  275.     if(aModel == NULL) continue;
  276.     pushmatrix();
  277.     rotate(aModel->rotation.z , 'z');
  278.         /* rotate(aModel->rotation.y , 'y'); /* not needed yet */
  279.         /* rotate(aModel->rotation.x , 'x'); /* not needed yet */
  280.     translate((float)aModel->translate.x,
  281.           (float)aModel->translate.y,
  282.           (float)aModel->translate.z);
  283.     scale(aModel->scale.x, aModel->scale.y, aModel->scale.z);
  284.  
  285.         /* don't draw model segments which are too declasse for the user */
  286.     if (aModel->declasse <= unsophistication)
  287.         drawobj(aModel, indiv);
  288.  
  289.         /* after drawing this model segment, draw its kids' models */
  290.     drawModel(aModel->kids, indiv, 1);
  291.  
  292.  
  293.     popmatrix();
  294.     }
  295. }
  296.  
  297.     /*
  298.      * draw a model segment, compiling it if necessary
  299.      */
  300. drawobj(m, indiv)
  301.     register model *m;
  302.     individual *indiv;
  303. {
  304.     register long *v;
  305.     register point *pnts = m->points;
  306.     register point *p, *p1;
  307.     Object oldobj;
  308.  
  309.     if(!m->compiled) {
  310.     oldobj = getopenobj();
  311.     m->component = (Object)m;
  312.     makeobj(m->component);
  313.         pushLongName(indiv);
  314.         pushmatrix();
  315.         /* draw the polygonal areas */
  316.         if (m->color < BACK_GROUND_BASE)
  317.          fishWritemask(FOREGROUND);
  318.         else fishWritemask(BACKGROUND);
  319.         fishColor(m->color);
  320.         if(m->texture)
  321.         setpattern(m->texture);
  322.         v = m->vertices;
  323.         while(*v) {
  324.         p = &pnts[*(v++)];
  325.         pmvi(p->x, p->y, p->z);
  326.         while(*v) {
  327.             p = &pnts[*(v++)];
  328.             pdri(p->x, p->y, p->z);
  329.         }
  330.         pclos();
  331.         v++;
  332.         }
  333.         /* outline the polygons */
  334.         if (m->outlined) {
  335.         fishColor(EDGE_COLOR);
  336.         v = m->vertices;
  337.         while(*v) {
  338.             p1 = p = &pnts[*(v++)];
  339.             movei(p->x, p->y, p->z);
  340.             while(*v) {
  341.             p = &pnts[*(v++)];
  342.             drawi(p->x, p->y, p->z);
  343.             }
  344.             drawi(p1->x, p1->y, p1->z);
  345.             /* v++;    /* VISUAL HACK; only draw 1st poly's edge */
  346.         }
  347.         }
  348.         popmatrix();
  349.         popLongName();
  350.     closeobj();
  351.     if (oldobj != -1)
  352.         editobj(oldobj);
  353.     m->compiled = TRUE;
  354.     }
  355.     callobj(m->component);
  356. }
  357.  
  358.     /*
  359.      * check each model segment in the individual, to see if a bad
  360.      * model color index has been assigned to it
  361.      */
  362. badModelIndex(firstModel, indiv)
  363.     register model *firstModel;
  364.     register individual *indiv;
  365. {
  366.     register model *aModel;
  367.     register int r = FALSE;
  368.     
  369.     for (aModel = firstModel; aModel ; aModel = aModel->next) {
  370.  
  371.     if (aModel->color == MODEL_COLOR_BASE)
  372.         return TRUE;
  373.  
  374.         /* after checking this model segment, check its kids' models */
  375.     if (r = badModelIndex(aModel->kids, indiv))
  376.         return r;
  377.     }
  378.     return r;
  379. }
  380.  
  381.     /*
  382.      *  gffree up an individual and all of his alloc'd mems
  383.      */
  384. freeIndividual(self)
  385.     register individual *self;
  386. {
  387.     register subscr *s;
  388.  
  389. /***************
  390.     dumpSubscribers("self's subscribers", self->them.subscribers);
  391. ***************/
  392.     if(isSuper(self,GUPPY))
  393.     fishPop--;
  394.     while (s = self->them.subscribers)
  395.     unsubscribe(self, s->member);
  396.  
  397. /***************
  398.     dumpSubscribers("self's subscribedTos", self->them.subscribedTo);
  399. ***************/
  400.     while (s = self->them.subscribedTo)
  401.     unsubscribe(s->member, self);
  402.  
  403.     if (self == curIndiv)
  404.     curIndiv = NULL;
  405.  
  406.     freeMsegs(self->descr);
  407.     dontdo(self);
  408.     gffree(self);
  409. }
  410.  
  411.     /*
  412.      * gffree a model tree, beginning with firstModel
  413.      */
  414. freeMsegs(firstModel)
  415.     register model *firstModel;
  416. {
  417.     register model *m, *nextm;
  418.  
  419.     for (m = firstModel; m; m = nextm) {
  420.     nextm = m->next;
  421.     delobj(m->component);
  422.     freeMapIndex(m->color);
  423.     freeMsegs(m->kids);
  424.     gffree(m);
  425.     }
  426. }
  427.  
  428.     /*
  429.      *  begin picking on an individual (button goes down on it)
  430.      */
  431. bselIndividual(self, argtype, hit)
  432.     register individual *self;
  433.     long argtype;
  434.     hitstruct *hit;
  435. {
  436.     /* printf("bselIndividual:    BEGIN SELECT on 0x%x, class %d\n",
  437.             self, ((inst *)self)->myClass->classId); /* */
  438.  
  439.     Msg(self, SELECT, argtype, hit);
  440. }
  441.  
  442.     /*
  443.      *  begin picking on a new individual (button wanders into it while down)
  444.      */
  445. nselIndividual(self, argtype, hit)
  446.     register individual *self;
  447.     long argtype;
  448.     hitstruct *hit;
  449. {
  450.     /* printf("nselIndividual:      NEW SELECT on 0x%x, class %d\n",
  451.             self, ((inst *)self)->myClass->classId); /* */
  452.  
  453.     Msg(self, SELECT, argtype, hit);
  454. }
  455.  
  456.  
  457.     /*
  458.      *  continue picking on an individual (button remains down on it)
  459.      */
  460. /* ARGSUSED */
  461. cselIndividual(self, argtype, hit)
  462.     register individual *self;
  463.     long argtype;
  464.     hitstruct *hit;
  465. {
  466.     /* printf("cselIndividual: CONTINUE SELECT on 0x%x, class %d\n",
  467.             self, ((inst *)self)->myClass->classId); /* */
  468. }
  469.  
  470.     /*
  471.      *  end picking on an individual (button goes up on it)
  472.      */
  473. /* ARGSUSED */
  474. eselIndividual(self, argtype, hit)
  475.     register individual *self;
  476.     long argtype;
  477.     hitstruct *hit;
  478. {
  479.     /* printf("eselIndividual:      END SELECT on 0x%x, class %d\n",
  480.             self, ((inst *)self)->myClass->classId); /* */
  481. }
  482.  
  483.     /*
  484.      *  no longer picking on an individual (button leaves it while down)
  485.      */
  486. /* ARGSUSED */
  487. oselIndividual(self, argtype, hit)
  488.     register individual *self;
  489.     long argtype;
  490.     hitstruct *hit;
  491. {
  492.     /* printf("oselIndividual:      OLD SELECT on 0x%x, class %d\n",
  493.             self, ((inst *)self)->myClass->classId); /* */
  494. }
  495.  
  496.     /*
  497.      *  begin picking on nothing (button goes down on it)
  498.      */
  499. /* ARGSUSED */
  500. bselNone(self, argtype, hit)
  501.     register individual *self;
  502.     long argtype;
  503.     hitstruct *hit;
  504. {
  505.     /* printf("bselNone:      BEGIN SELECT on NOTHING\n"); /* */
  506.  
  507.     inNothing = TRUE;
  508. }
  509.  
  510.     /*
  511.      *  end picking on nothing (button goes up on it)
  512.      */
  513. /* ARGSUSED */
  514. eselNone(self, argtype, hit)
  515.     register individual *self;
  516.     long argtype;
  517.     hitstruct *hit;
  518. {
  519.     /* printf("eselNone:      END SELECT on NOTHING\n"); /* */
  520.  
  521.     if (inNothing) {
  522.     /***********
  523.     if (curIndiv) {
  524.         Msg(curIndiv, DESELECT, NOARG, NULL);
  525.     }
  526.     **********/
  527.     controls = !controls;
  528.     }
  529. }
  530.  
  531. /* ARGSUSED */
  532. selectIndiv(self, argtype, hit)
  533.     register individual *self;
  534.     long argtype;
  535.     hitstruct *hit;
  536. {
  537.     inNothing = FALSE;
  538.  
  539.     if (self != curIndiv) {
  540.     if (curIndiv)
  541.         Msg(curIndiv, DESELECT, NOARG, NULL);
  542.     self->flags |= PICKED;
  543.     curIndiv = self;
  544.     controls = TRUE;
  545.     emptyPanel(thePanel);
  546.     Msg(thePanel, INIT, NOARG, NULL);
  547.     
  548.     Msg(self, ADDPANEL, NOARG, NULL);
  549.     }
  550. }
  551.  
  552. deselectIndiv(self)
  553.     register individual *self;
  554. {
  555.     if (self) {
  556.     self->flags &= ~PICKED;
  557.         if (self != curIndiv)
  558.             return;
  559.     removePanel(self);
  560.     }
  561.     curIndiv = NULL;
  562. }
  563.  
  564. /* ARGSUSED */
  565. addBehavior(self, argtype, doer)
  566.     register individual *self;
  567.     int argtype;
  568.     behavior *doer;
  569. {
  570.     panel *aPanel;
  571.  
  572.     if (! (aPanel = (panel *)self->controls)) {
  573.     printf("addBehavior: current individual has no panel.\n");
  574.     return;
  575.     }
  576.     subscribe(doer, self);
  577.     self->curVars = self->them.subscribedTo;
  578.     /* printf("addBehavior: calling addpanel for behavior %d\n",
  579.              doer->them.me.myClass->classId); /* */
  580.     Msg(doer, ADDPANEL, INTARG, self);
  581. }
  582.  
  583. postIndividual(self, argtype, doer)
  584.     register individual *self;
  585.     int argtype;
  586.     behavior *doer;
  587. {
  588.     subscr *sentry;
  589.  
  590.     /*
  591.      *  if already subscribed to posted behavior,
  592.      *  highlight it in the panel.
  593.      */
  594.     if (sentry = findvars(self, doer->them.me.myClass->classId)) {
  595.         /* printf("postIndividual: already have %d behavior\n",
  596.             doer->them.me.myClass->classId); /* */
  597.  
  598.     /*
  599.      *  else subscribe to it and add it to the panel.
  600.      */
  601.     } else {
  602.     addBehavior(self, argtype, doer);
  603.     }
  604. }
  605.  
  606. /* ARGSUSED */
  607. dieIndividual(self, argtype, arg)
  608.     register individual *self;
  609.     long argtype;
  610.     char *arg;
  611. {
  612.     expire(self, 40.0);
  613. }
  614.  
  615.     /*
  616.      *  snuff a fish, complete with burp
  617.      */
  618. expire(self, bubblesize)
  619.     register individual *self;
  620.     float bubblesize;
  621. {
  622.     expanderVars *bubVars;
  623.     individual *burp, *makeBub();
  624.  
  625.     burp = makeBub();
  626.     subscribe(us, burp);
  627.  
  628.     subscribe(&advancerTemplate, burp);
  629.     subscribe(&expanderTemplate, burp);
  630.     subscribe(&surfDieTemplate, burp);
  631.     Msg(burp, INIT, NOARG, NULL);
  632.  
  633.     if (bubVars = (expanderVars *)findvars(burp, EXPANDER)) {
  634.         bubVars->scaleMax = bubblesize;
  635.     }
  636.     burp->position.x = self->position.x;
  637.     burp->position.y = self->position.y;
  638.     burp->position.z = self->position.z;
  639.  
  640.     burp->lastPosition.x = burp->position.x - burp->velocity.x;
  641.     burp->lastPosition.y = burp->position.y - burp->velocity.y;
  642.     burp->lastPosition.z = burp->position.z - burp->velocity.z;
  643.  
  644.     Msg (self, DESELECT, 0, NULL);
  645.     Msg (self, FREE, 0, NULL);
  646. }
  647.  
  648.     /*
  649.      *  construct an individual's control panel
  650.      */
  651. addPanel(self)
  652.     register individual *self;
  653. {
  654.     register masterPanel *aPanel = thePanel;
  655.     register subscr *sentry;
  656.  
  657.     addIndivPanel(self, sizeof(masterPanel), aPanel);
  658.     /* append controls for each behavior the individual is subscribed to */
  659.     for (sentry = self->them.subscribedTo; sentry; sentry = sentry->next) {
  660.     self->curVars = sentry;
  661.     Msg(sentry->member, ADDPANEL, INTARG, self);
  662.     }
  663. }
  664.  
  665.  
  666. #define SPEEDER
  667. #ifdef SPEEDER
  668.     /*
  669.      *  initialize the individual's subtree of panels
  670.      */
  671. /* ARGSUSED */
  672. addIndivPanel(self, argtype, dad)
  673.     register individual *self;
  674.     long argtype;
  675.     register panel *dad;
  676. {
  677.     panel *p;
  678.     int flags;
  679.     rectangle  r, rw;
  680.     rectanglef rwf;
  681.     point2d inset, button;
  682.     extern panel *makeValuator(), *makeValuatorf();
  683.     extern panel *makeValDelta(), *makePanel(), *makeMenu();
  684.     extern panel *makeValMesg(), *makeValMesgf();
  685.  
  686.         /* individual's floor panel */
  687.     setrect(&r, 0,((masterPanel *)dad)->highwater.y, 255,155);
  688.     ((masterPanel *)dad)->highwater.y += 155;
  689.     buildIndFloor(&r, INDIVFLOOR);
  690.     p = dad->kids = makePanel(dad->kids, dad, &r, INDIVFLOOR);
  691.  
  692.     self->controls = (char *)p;
  693.  
  694.         /* individual's size control */
  695.     flags = NULL;
  696.     setrect(&r, 10,10, 52,100);
  697.     setpt2d(&inset, 0,6);
  698.     setrect(&rwf, 0.0,8.0, 0.0,-7.8);
  699.     buildIndSize(&r, ((inst *)self)->myClass->classId, INDSIZE, INDSIZET);
  700.     p->kids = makeValuatorf(p->kids, p, flags, &r, &inset, &rwf,
  701.                 NULL, &self->scale, INDSIZE, INDSIZET);
  702.  
  703.         /* NOTE: this valuator is out of paint order at its origin, */
  704.         /*  to avoid overlap from the heading control               */
  705.  
  706.         /* death to fish control */
  707.     flags = NULL;
  708.     setrect(&r, 105,85, 55,25);
  709.     setpt2d(&button, 1, 1);
  710.     buildIndSnuff(&r, ((inst *)self)->myClass->classId, INDSNUFF,INDSNUFFT);
  711.     p->kids = makeMenu(p->kids, p, flags, &r, &button,
  712.                 self, DIE, INDSNUFF, INDSNUFFT);
  713.  
  714.         /* individual's speed control */
  715.     flags = NULL;
  716.     setrect(&r, 10,120, 240,25);
  717.     setpt2d(&inset, 15,0);
  718.     setrect(&rwf, 200.0,0.0, -190.0,0.0);    /* speed from 10 to 200 */
  719.     buildIndSpeed(&r, ((inst *)self)->myClass->classId, INDSPEED,INDSPEEDT);
  720.     p->kids = makeValuatorf(p->kids, p, flags, &r, &inset, &rwf,
  721.                  &self->speed, NULL, INDSPEED, INDSPEEDT);
  722.  
  723.         /* individual's heading control */
  724.     flags = NULL;
  725.     setrect(&r, 72,10, 120,70);
  726.     setpt2d(&inset, 0,0);
  727.     setrect(&rwf, -0.2,0.0, 0.4,0.0);
  728.     buildIndHeading(&r, ((inst *)self)->myClass->classId, INDHEAD,INDHEADT);
  729.     p->kids = makeValMesgf(p->kids, p, flags, &r, &inset, &rwf, 0.0, 0.0,
  730.                 self, NEWHEADING, AUTORESET, INDHEAD, INDHEADT);
  731.  
  732.         /* individual's azimuth control */
  733.     flags = NULL;
  734.     setrect(&r, 202,10, 48,100);
  735.     setpt2d(&inset, 0,15);
  736.     setrect(&rw, 0,20, 0,-40);
  737.     buildIndAzimuth(&r, ((inst *)self)->myClass->classId, INDAZ, INDAZT);
  738.     p->kids = makeValMesg(p->kids, p, flags, &r, &inset, &rw, 0, 0,
  739.                 self, NEWAZIMUTH, NOAUTORESET, INDAZ, INDAZT);
  740.  
  741.         /* test menu buttons */
  742.         /*
  743.     flags = NULL;
  744.     setrect(&r, 10, 160, 200, 200);
  745.     setpt2d(&button, 4, 3);
  746.     buildMenu1(&r, &button, MENU1, MENUH1);
  747.     p->kids = makeMenu(p->kids, p, flags, &r, &button,
  748.                 self, TESTMENU, MENU1, MENUH1);
  749.     /* */
  750. }
  751.  
  752. #else /* SPEEDER */
  753.     /*
  754.      *  initialize the individual's subtree of panels
  755.      */
  756. addIndivPanel(self, argtype, dad)
  757.     register individual *self;
  758.     long argtype;
  759.     register panel *dad;
  760. {
  761.     panel *p;
  762.     int flags;
  763.     rectangle  r, rw;
  764.     rectanglef rwf;
  765.     point2d inset, button;
  766.     extern panel *makeValuator(), *makeValuatorf();
  767.     extern panel *makeValDelta(), *makePanel(), *makeMenu();
  768.     extern panel *makeValMesg(), *makeValMesgf();
  769.  
  770.         /* individual's floor panel */
  771.     setrect(&r, 0,((masterPanel *)dad)->highwater.y, 255,120);
  772.     ((masterPanel *)dad)->highwater.y += 120;
  773.     buildIndFloor(&r, INDIVFLOOR);
  774.     p = dad->kids = makePanel(dad->kids, dad, &r, INDIVFLOOR);
  775.  
  776.     self->controls = (char *)p;
  777.  
  778.         /* individual's size control */
  779.     flags = NULL;
  780.     setrect(&r, 10,10, 52,100);
  781.     setpt2d(&inset, 0,6);
  782.     setrect(&rwf, 0.0,8.0, 0.0,-7.8);
  783.     buildIndSize(&r, ((inst *)self)->myClass->classId, INDSIZE, INDSIZET);
  784.     p->kids = makeValuatorf(p->kids, p, flags, &r, &inset, &rwf,
  785.                 NULL, &self->scale, INDSIZE, INDSIZET);
  786.  
  787.         /* individual's color control */
  788. /*    flags = NULL;
  789. /*    setrect(&r, 72,10, 192,50);
  790. /*  initColorVals(p, flags, &r, self->descr->color);
  791. /* */
  792.         /* death to fish control */
  793.     flags = NULL;
  794.     setrect(&r, 130,10, 50,100);
  795.     setpt2d(&button, 1, 1);
  796.     buildIndSnuff(&r, ((inst *)self)->myClass->classId, INDSNUFF,INDSNUFFT);
  797.     p->kids = makeMenu(p->kids, p, flags, &r, &button,
  798.                 self, DIE, INDSNUFF, INDSNUFFT);
  799.  
  800.         /* individual's azimuth control */
  801.     flags = NULL;
  802.     setrect(&r, 72,10, 48,100);
  803.     setpt2d(&inset, 0,15);
  804.     setrect(&rw, 0,20, 0,-40);
  805.     buildIndAzimuth(&r, ((inst *)self)->myClass->classId, INDAZ, INDAZT);
  806.     p->kids = makeValMesg(p->kids, p, flags, &r, &inset, &rw, 0, 0,
  807.                 self, NEWAZIMUTH, NOAUTORESET, INDAZ, INDAZT);
  808.  
  809.         /* test menu buttons */
  810.         /*
  811.     flags = NULL;
  812.     setrect(&r, 10, 160, 200, 200);
  813.     setpt2d(&button, 4, 3);
  814.     buildMenu1(&r, &button, MENU1, MENUH1);
  815.     p->kids = makeMenu(p->kids, p, flags, &r, &button,
  816.                 self, TESTMENU, MENU1, MENUH1);
  817.     /* */
  818. }
  819. #endif /* SPEEDER */
  820.  
  821.     /*
  822.      *  discard an obsolete Individual's control panel
  823.      */
  824. removePanel(self)
  825.     register individual *self;
  826. {
  827.     self->controls = NULL;
  828.     Msg(thePanel, INIT, NOARG, NULL);
  829. }
  830.  
  831. burp(s,wanted)
  832.     char *s;
  833.     inst * wanted;
  834. {
  835.     printf("hickup in %s\n", s);
  836.     dumper = 1;
  837.     dumpSubscribers("whole thing:", us->them.subscribers, wanted);
  838.     dumper = 0;
  839. }
  840.